#include "stdafx.h"
#include "ScreenManager.h"

using namespace MomogenkyouSystem;


std::deque<ScreenTemplate	*>	ScreenManager::m_Screens;
std::deque<ScreenTemplate	*>	ScreenManager::m_ScreensToUpdate;
TEXTURE							ScreenManager::g_pBlankTexture(NULL);
SPRITEBATCH						ScreenManager::g_pSpriteBatch(NULL);

void	ScreenManager::Initialize()
{
	HRESULT	_Result(S_OK);
	_Result = D3DXCreateSprite(GraphicsSystem::Device, &g_pSpriteBatch);
	ASSERT(_Result == S_OK, "ScreenMaanger > Error Creating SpriteBatch");
	_Result = D3DXCreateTextureFromFile(GraphicsSystem::Device, L"Data/Base/BlankTexture.png", &g_pBlankTexture);
	ASSERT(_Result == S_OK, "ScreenMaanger > Error Creating BlankTexture") ;
}

void	ScreenManager::Shutdown()
{
	m_ScreensToUpdate.clear();
	for(size_t i = 0; i < m_Screens.size(); i++)
	{
		m_Screens[i]->Shutdown();
	}
	m_Screens.clear();
	g_pBlankTexture->Release();
	g_pSpriteBatch->Release();
}


void	ScreenManager::AddScreen(ScreenTemplate * pScreen)
{
	//pScreen->g_pScreenManager = SmartPtr<ScreenManager>(this);
	pScreen->m_bIsExiting = false;
	pScreen->Initialize();
	m_Screens.push_back(pScreen);
}

void	ScreenManager::RemoveScreen(ScreenTemplate * pScreen)
{
	pScreen->Shutdown();
	
	std::deque<ScreenTemplate *>::iterator it;
	for(it = m_Screens.begin(); it != m_Screens.end(); it++)
	{
		if(*it != pScreen)	continue;
		*it = NULL;
		m_Screens.erase(it);
		break;
	}
	

	for(it = m_ScreensToUpdate.begin(); it != m_ScreensToUpdate.end(); it++)
	{
		if(*it != pScreen)	continue;
		*it = NULL;
		m_ScreensToUpdate.erase(it);
		break;
	}
}


void	ScreenManager::FadeBackBufferToBlack(const int & nAlpha)
{
	RECT	_ScreenRectangle;
	_ScreenRectangle.left	=	0;
	_ScreenRectangle.top	=	0;
	_ScreenRectangle.right	=	GraphicsSystem::ViewPort.Width;
	_ScreenRectangle.bottom =	GraphicsSystem::ViewPort.Height;

	g_pSpriteBatch->Begin(D3DXSPRITE_ALPHABLEND);
	g_pSpriteBatch->Draw(g_pBlankTexture, &_ScreenRectangle, NULL, NULL, ARGB(nAlpha, 0, 0, 0));
	g_pSpriteBatch->End();
}


void	ScreenManager::UpdateScreens(const float & fInterval)
{
	m_ScreensToUpdate.clear();
	m_ScreensToUpdate = m_Screens;

	bool	_OtherScreenFocus(false);	//!game.Active
	bool	_CoveredByScreen(false);

	ScreenTemplate	*	_ScreenReference(NULL);

	while(m_ScreensToUpdate.size() > 0)
	{
		_ScreenReference = m_ScreensToUpdate.back();
		m_ScreensToUpdate.erase(m_ScreensToUpdate.end() - 1);

		_ScreenReference->UpdateScreen(fInterval, _OtherScreenFocus, _CoveredByScreen);

		if(_ScreenReference->ScreenState() == TransitionOn || _ScreenReference->ScreenState() == Active)
		{
			if(!_OtherScreenFocus)
			{
				_ScreenReference->ProcessInput();
				if(_ScreenReference->IsModal)
					_OtherScreenFocus = true;

			}
			if(!_ScreenReference->IsPopup())
				_CoveredByScreen = true;
		}
	}
}

void	ScreenManager::RenderScreens(const float & fInterval)
{
	for(size_t i = 0; i < m_Screens.size(); i++)
	{
		if(m_Screens[i]->ScreenState() == Hidden)	continue;
		m_Screens[i]->DrawGameScreen(fInterval);
	}
}

#if _DEBUG
void	ScreenManager::CmdOutput()
{
	for(size_t i = 0; i < m_Screens.size(); i++)
	{
		WriteCommandLine("Screen %i : %s", i, m_Screens[i]->ScreenName().c_str());
	}
}
#endif